<!--
 @description PopDateTimePicker
 @fileName index.vue
 @author zengqiongying
 @created 2022/10/30 14:04:30
-->
<template>
  <Popup
    v-model="popShow"
    position="bottom"
    :title="title"
    :show-cancel-button="false"
    :clear="clear"
    @confirm="handleSubmit"
    @clear="handleClear"
  >
    <qmp-calendar
      ref="calendar"
      class="cus-calendar-time"
      color="#05C4C3"
      :type="calendarType"
      :show-title="true"
      :poppable="false"
      :show-confirm="false"
      :row-height="50"
      :default-date="defaultDate"
      :style="{ height: '70vh' }"
      allow-same-day
      v-bind="$attrs"
      @confirm="onCalendarConfirm"
      @select="onCalendarSelect"
    >
      <template #title>
        <div class="calendar-title">
          <qmp-field
            v-model="start"
            left-icon="calendar-o"
            class="cus-field"
            label=""
            readonly
            :placeholder="`${calendarType === 'range' ? '开始' : '日期'}${showTime ? '时间' : '日期'}`"
            @click="handleClickTime('start')"
          />
          <template v-if="calendarType === 'range'">
            <div class="separator"></div>
            <qmp-field
              v-model="end"
              left-icon="calendar-o"
              class="cus-field"
              label=""
              readonly
              placeholder="结束日期"
              @click="handleClickTime('end')"
            />
          </template>
          <!-- <div v-show="startDate" class="btn-clear-date" @click.stop="handleClearDate">清除日期</div> -->
        </div>
      </template>
    </qmp-calendar>
    <qmp-popup v-if="showPicker" v-model:show="showPicker" round position="bottom" @opened="handlePopupOpen">
      <qmp-picker
        ref="picker"
        show-toolbar
        :columns="columns"
        swipe-duration="500"
        visible-item-count="5"
        @cancel="showPicker = false"
        @change="onPickerChange"
      >
        <div class="picker-title">
          <span>{{ pickerText }}(时分秒)</span>
          <span class="btn-confirm" @click="handleTimeconfirm">确定</span>
        </div>
      </qmp-picker>
    </qmp-popup>
  </Popup>
</template>

<script lang="ts">
  import { ref, reactive, toRefs, defineComponent, computed, watch, nextTick, getCurrentInstance } from 'vue'
  import Popup from '@/components/Popup/index.vue'
  import moment from 'moment'
  import { columnsList } from './columns'

  interface anyObjectModle {
    [key: string]: any
  }
  export default defineComponent({
    name: 'PopDateTimePicker',
    components: { Popup },
    props: {
      modelValue: {
        type: Boolean,
        default: false
      },
      title: {
        type: String,
        default: ''
      },
      calendarType: {
        type: String,
        default: 'single'
      }, // 日历选择类型：single表示选择单个日期，range 表示选择日期区间,multiple表示选择多个日期(暂不支持)
      defaultValue: {
        type: [String, Array],
        default: ''
      },
      showTime: {
        type: Boolean,
        default: false
      },
      clear: {
        type: Boolean,
        default: false
      }
    },
    emits: ['change', 'update:modelValue', 'confirm'],
    setup(props, { emit }) {
      const { proxy }: any = getCurrentInstance()
      const calendar = ref()
      const picker = ref()
      const datas = reactive<anyObjectModle>({
        defaultDate: null,
        columns: columnsList,
        show: false,
        pickerText: '时间',
        isDisabled: true,
        showPicker: false,
        startDate: '',
        endDate: '',
        startTime: '',
        endTime: '',
        timeValue: ''
      })

      const formatTime = (d: any) => {
        const h = moment(d).hour()
        const m = moment(d).minute()
        const s = moment(d).second()
        return {
          h: h < 10 ? '0' + h : h,
          m: m < 10 ? '0' + m : m,
          s: s < 10 ? '0' + s : s
        }
      }
      const popShow = computed({
        set(val) {
          emit('update:modelValue', val)
        },
        get() {
          return props.modelValue
        }
      })
      const start = computed(() => {
        if (!props.showTime) return datas.startDate
        const val = datas.startDate + ' ' + datas.startTime
        return val.trim()
      })
      const end = computed(() => {
        if (!props.showTime) return datas.endDate
        const val = datas.endDate + ' ' + datas.endTime
        return val.trim()
      })
      watch(
        () => props.calendarType,
        (val) => {
          datas.pickerText = val === 'range' ? '开始时间' : '时间'
        }
      )
      // 初始默认日历
      watch(
        () => props.defaultValue,
        (val: any) => {
          const d = new Date()
          if (props.calendarType === 'single') {
            const d1 = val ? new Date(val) : d
            datas.defaultDate = d1
            datas.startDate = moment(d1).format('YYYY-MM-DD')
            const t = formatTime(d1)
            datas.startTime = `${t.h}:${t.m}:${t.s}`
          } else if (props.calendarType === 'range') {
            if (val instanceof Array && val.length === 2) {
              const d1 = new Date(val[0])
              const d2 = new Date(val[1])
              datas.defaultDate = [d1, d2]

              datas.startDate = moment(d1).format('YYYY-MM-DD')
              const t1 = formatTime(d1)
              datas.startTime = `${t1.h}:${t1.m}:${t1.s}`

              datas.endDate = moment(d2).format('YYYY-MM-DD')
              const t2 = formatTime(d2)
              datas.endTime = `${t2.h}:${t2.m}:${t2.s}`
              return
            }
            datas.defaultDate = [d, d]
            datas.startDate = moment(d).format('YYYY-MM-DD')
            datas.endDate = moment(d).format('YYYY-MM-DD')
            datas.startTime = `00:00:00`
            datas.endTime = `23:59:59`
          }

          if (datas.pickerText === '开始时间' || datas.pickerText === '时间') {
            datas.timeValue = datas.startTime
          } else {
            datas.timeValue = datas.endTime
          }
        },
        {
          deep: true,
          immediate: true
        }
      )
      watch(
        () => datas.startDate,
        () => {
          datas.isDisabled = true
        }
      )
      watch(
        () => datas.endTime,
        (val) => {
          if (!val) {
            return
          }
          if (moment(end.value).isBefore(moment(start.value))) {
            datas.startTime = datas.endTime
          }
          datas.isDisabled = false
        }
      )
      watch(
        () => popShow,
        (val) => {
          if (val) {
            if (datas.defaultDate) {
              const date = new Date(datas.defaultDate)
              nextTick(() => {
                setTimeout(() => {
                  calendar.value.scrollToDate(date)
                }, 1000)
              })
            }
          }
        }
      )
      // 清除日历数据
      const handleClearDate = () => {
        calendar.value.reset()
        Object.assign(datas, {
          pickerText: props.calendarType === 'range' ? '开始时间' : '时间',
          isDisabled: true,
          startDate: '',
          endDate: '',
          startTime: '',
          endTime: '',
          timeValue: ''
        })
      }

      const handlePopupOpen = () => {
        if (datas.pickerText === '开始时间' || datas.pickerText === '时间') {
          picker.value.setIndexes([8, 0, 0])
        }
        const value = picker.value.getValues()
        const str = value.join(':')
        datas.timeValue = str
        if (datas.pickerText === '开始时间' || datas.pickerText === '时间') {
          datas.startTime = str
          return
        }
        datas.endTime = str
      }
      const handleTimeconfirm = () => {
        const str = datas.timeValue
        if (datas.pickerText === '开始时间' || datas.pickerText === '时间') {
          datas.startTime = str
          datas.showPicker = false
          return
        }
        datas.endTime = str
        datas.showPicker = false
      }
      const onPickerChange = (value: any, index: number) => {
        const str = value.join(':')
        datas.timeValue = str
      }
      const onCalendarConfirm = () => {
        emit('confirm', { startTime: start.value, endTime: end.value })
        datas.show = false
      }
      // 设置时分秒默认选中值
      const initTimeDefault = (datetime: any) => {
        const time = datetime || new Date()
        const h = moment(time).hour()
        const m = moment(time).minute()
        const s = moment(time).second()
        const colvalues = [`${h < 10 ? '0' + h : h}`, `${m < 10 ? '0' + m : m}`, `${s < 10 ? '0' + s : s}`]
        columnsList.forEach((c: any, i: number) => {
          const index = c.values.indexOf(colvalues[i])
          c.defaultIndex = index === -1 ? 0 : index
        })
      }

      const onCalendarSelect = (val: any) => {
        const now = new Date()
        const h = moment(now).hour()
        const m = moment(now).minute()
        const s = moment(now).second()
        const nowTime = `${h < 10 ? '0' + h : h}:${m < 10 ? '0' + m : m}:${s < 10 ? '0' + s : s}`

        if (props.calendarType !== 'range') {
          datas.endDate = ''
          datas.endTime = ''
          datas.startDate = moment(val).format('YYYY-MM-DD')
          datas.pickerText = '时间'
          if (datas.startTime === '') {
            datas.startTime = nowTime
          }
          initTimeDefault(`${datas.startDate} ${datas.startTime}`)

          if (!props.showTime) return
          datas.showPicker = true
          return
        }
        if (val[1]) {
          datas.endDate = moment(val[1]).format('YYYY-MM-DD')
          datas.pickerText = '结束时间'
          if (datas.endTime === '') {
            datas.endTime = nowTime
          }
          initTimeDefault(`${datas.endDate} ${datas.endTime}`)
        } else {
          if (end.value) {
            datas.endDate = ''
            datas.endTime = ''
          }
          datas.startDate = moment(val[0]).format('YYYY-MM-DD')
          datas.pickerText = '开始时间'
          if (datas.startTime === '') {
            datas.startTime = nowTime
          }
          initTimeDefault(`${datas.startDate} ${datas.startTime}`)
        }
        if (!props.showTime) return
        datas.showPicker = true
      }
      const handleClickTime = (type: any) => {
        if (!props.showTime) return
        if (type === 'end') {
          if (end.value === '') {
            return
          }
          datas.pickerText = '结束时间'
          initTimeDefault(end.value)
        } else {
          if (start.value === '') {
            return
          }
          datas.pickerText = props.calendarType === 'range' ? '开始时间' : '时间'
          initTimeDefault(start.value)
          datas.showPicker = true
        }
      }

      const handleClear = () => {
        handleClearDate()
        emit('change', '')
        emit('update:modelValue', false)
      }
      const handleSubmit = () => {
        let dateTime = null
        const txt = props.showTime ? '时间' : '日期'
        if (props.calendarType === 'range') {
          if (start.value === '' || end.value === '') {
            proxy.$toast(`请选择开始${txt}和结束${txt}`)
            return
          }
          dateTime = [start.value, end.value]
        } else {
          if (start.value === '') {
            proxy.$toast(
              `请选择${
                props.calendarType === 'range'
                  ? props.showTime
                    ? '开始时间'
                    : '开始日期'
                  : props.showTime
                  ? '时间'
                  : '日期'
              }`
            )
            return
          }
          dateTime = start.value
        }
        emit('change', dateTime)
        emit('update:modelValue', false)
      }

      datas.pickerText = datas.calendarType === 'range' ? '开始时间' : '时间'
      return {
        ...toRefs(datas),
        popShow,
        start,
        end,
        handleClearDate,
        handlePopupOpen,
        handleTimeconfirm,
        onPickerChange,
        onCalendarConfirm,
        onCalendarSelect,
        handleClickTime,
        handleSubmit,
        handleClear
      }
    }
  })
</script>
<style lang="less" scoped>
  .cus-calendar-time.qmp-calendar {
    height: 360px !important;
  }
  /deep/ [class*='qmp-hairline']::after {
    border-color: #00c8b4;
    border-width: 2px 0;
  }
  /deep/ .qmp-picker-column__item--selected {
    font-size: 18px;
    font-weight: bold;
  }

  .calendar-title {
    position: relative;
    width: 100%;
    box-sizing: border-box;
    display: flex;
    align-items: center;
    justify-content: space-between;
    .cus-field {
      flex: 1;
      height: 36px;
      line-height: 20px;
      background: rgba(241, 241, 242, 0.5);
      padding: 8px 3px;
      font-weight: normal;
    }
    .separator {
      margin: 0 5px;
      width: 10px;
      height: 1px;
      background: #b5b7c4;
      border-radius: 1px;
    }
    .btn-clear-date {
      position: absolute;
      left: 0;
      top: -20px;
      color: #101a52;
      font-size: 14px;
      line-height: 18px;
      font-weight: bold;
      z-index: 9;
    }
  }

  /deep/ .qmp-picker__toolbar {
    justify-content: center;
    font-weight: 500;
  }
  /deep/ .qmp-calendar__bottom-info {
    bottom: 4px;
  }
  .picker-title {
    width: 100%;
    position: relative;
    font-weight: bold;
    font-size: 14px;
    text-align: center;
    .btn-confirm {
      position: absolute;
      right: 10px;
      top: 0;
      z-index: 9;
      font-weight: normal;
      font-size: 12px;
      color: #009e77;
    }
  }
</style>
